<template>
  <div class="foods-container">
    <!-- 侧边栏 -->
    <div class="cate-list-wrap">
      <ul class="cate-list" >
        <li  v-for="(cate,index) in foodData" :key="cate.id"
          :class="{'cate-item':true, 'cate-item-active':cateIndex==index}"
          @click="onCateClick(index)"
        >
          <p class="cate-text">{{cate.name}}</p>
          <div v-if="categoryAddNums[cate.id]" class="cate-badge badge">{{categoryAddNums[cate.id]}}</div>
        </li>
      </ul>
    </div>
    <!-- 商品列表 -->
    <div class="food-list-wrap">
      <!-- 滚动内容 -->
      <div class="food-list">
        <!-- 某一种类别的所有商品列表 -->
        <ul class="cate-foods-wrap" v-for="cate in foodData" :key="cate.id">
          <li class="cate-food-header">
            <span class="food-header-title">{{cate.name}}</span>
            <span class="food-header-desc">{{cate.description}}</span>
            <van-icon class="food-header-more" name="ellipsis" />
          </li>
          <li class="food-item-box" 
            v-for="item in cate.foods" :key="item.item_id"
          >
            <div class="attr-new" v-if="judgeNew(item.attributes)">
              <p>新品</p>
            </div>
            <img :src="imgOrigin+item.image_path" alt="" class="foodicon">
            <div class="foodinfo">
              <div class="row">
                <div class="food-title">{{item.name}}</div>
                <div class="food-labels" v-if="judgeSign(item.attributes)">
                  <span class="food-label"
                  style="color:#f07373;border-color:#f07373;"
                  >招牌</span>
                </div>
              </div>
              <div class="row">
                <div class="food-desc">{{item.description}}</div>
              </div>
              <div class="row">
                <span class="food-tips">月售{{item.month_sales}}份 好评率{{item.satisfy_rate|toPercent}}</span>
              </div>
              <div class="row">
                <div class="food-fee">
                  <span>￥</span>
                  <span>{{item.specfoods[0].price}}</span>
                  <span>起</span>
                </div>
                <elm-counter v-model="item.add_car_count" 
                  :restaurant_id="shopId" 
                  :category_id="cate.id"
                  :item_id="item.item_id"
                  :product="item.specfoods.length===1?item.specfoods[0]:{}"
                  :specifications="item.specfoods.length===1?{}:item.specifications[0]"
                  :specProducts="item.specfoods.length===1?[]:item.specfoods"
                  @onSelectSpecs="onSelectSpecs"
                  @afterAddToCart="afterAddToCart"
                  >
                </elm-counter>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <!-- 外置标题头，用于吸顶 -->
      <div ref="foodListHeaderRef" class="cate-food-header sticky-fixed">
        <span class="food-header-title">{{foodData[cateIndex].name}}</span>
        <span class="food-header-desc">{{foodData[cateIndex].description}}</span>
        <van-icon class="food-header-more" name="ellipsis" />
      </div>
    </div>
    <!-- 购物车蒙层 -->
    <van-overlay id="cartOverlay" :show="showCarDialog" 
      @click="handleCartOverlayClick"
      :lock-scroll="false">
      <!-- 购物车商品列表 -->
      <div  class="shop-car-food-wrap">
        <div class="shop-car-food-header">
          <span>购物车</span>
          <div class="car-clear-btn" @click="handleCartClear">
            <van-icon name="delete-o" />
            <span>清空</span>
          </div>
        </div>
        <div class="shop-car-food-list">
          <div class="shop-car-food"
            v-for="food in cartFoodList" :key="food.id"
          >
            <div class="shop-car-food-name-wrap">
              <p class="shop-car-food-name">{{food.name}}</p> 
              <p class="shop-car-food-spec" v-if="food.specs[0]">{{food.specs[0].value}}</p>
            </div>
            <div class="shop-car-food-right">
              <span class="shop-car-food-price">{{food.price}}</span>
              <elm-counter v-model="food.add_car_count" 
                :restaurant_id="shopId" 
                :category_id="food.category_id"
                :item_id="food.item_id"
                :product="food"
                :listenOnChange="true"
                @onChange="handleCartCountChange"
                >
              </elm-counter>
            </div>
          </div>
        </div>
      </div>
    </van-overlay>
    <!-- 购物车底栏 -->
    <div class="shop-car">
      <div ref="shopCartRef" :class="{'shop-car-icon':true,'shop-car-icon-active':cartNum>0, 'cart-animation':showCartAnimation}" 
        @click="toggleCarDialog">
        <van-icon  name="shopping-cart" />
        <div v-if="cartNum>0" class="cart-badge badge">{{cartNum}}</div>
      </div>
      
      <div class="shop-car-info">
        <div class="info-main">￥{{cartTotalPrice}}</div>
        <div class="info-secd">配送费{{shopDetail.float_delivery_fee}}</div>
      </div>
      <div v-if="needOrderAmount>0" class="shop-car-btn">还差￥{{needOrderAmount}}起送</div>
      <div v-else class="shop-car-btn" style="background-color:#4cd964"
        @click="navCheckout"
      >去结算</div>
    </div>
    <!-- 规格选择弹框 -->
    <van-popup v-model="showSpecsDialog">
      <!-- <div class="specs-box"> -->
        <van-icon class="close-icon" name="cross" @click="showSpecsDialog=false"/>
        <div class="specs-title">{{specProducts[0]&&specProducts[0].name}}</div>
        <div class="specs-content" v-if="specifications.name">
          <p>{{specifications.name}}</p>
          <span v-for="(val,index) in specifications.values" :key="val"
            :class="{'specs-item':true,'specs-item-active':index===activeSpecsKey}"
            @click="onSpecClick(index)"
          >{{val}}</span>
        </div>
        <div class="specs-footer">
          <span class="specs-price">20</span>
          <span class="specs-add-btn" @click="addSpecToCart">加入购物车</span>
        </div>
      <!-- </div> -->
    </van-popup>
    <!-- 加入购物车的小球(过渡动画) -->
    <transition 
      @before-enter="beforeEnter"  
      @enter="enter"
      @after-enter="afterEnter"
     >
      <div class="ball-box" v-if="showBall">
        <img src="../../../images/icon-add.png" 
          class="ball">
      </div>
    </transition>
  </div>
</template>
<script>
import BScroll from '@better-scroll/core'
import elmCounter from './elmCounter'
import {mapState, mapActions} from 'vuex'
import { CLEAR_PRODUCTS } from '../../../store/mutationTypes'
import varStyles from '../../../styles/var.scss'
export default {
  components:{
    'elm-counter':elmCounter
  },
  props:{
    shopId:null,
    shopDetail:{
      type: Object,
      default:_=>{}
    },
    shopFoods:{
      type: Array,
      default: _=>[]
    }
  },
  created(){
    const foodData = [...this.shopFoods]
    for(let dt of foodData){
      // 加上数量标记add_car_count
      dt.foods.forEach(item=>{
        const findFood = this.cartFoodList.find(food=>{
          return food.item_id == item.item_id
        })
        item.add_car_count = findFood ? findFood.quantity : 0
      })
    } 
    this.foodData = foodData
  },
  mounted(){
    /* 这里有个巨坑！问题：第一次路由进入页面获取的元素高度存在较大误差，和之后的高度不一样
      我这里已分析出是elm-counter组件高度不固定造成，所以在计算长列表高度时，尽量对元素使用固定高度，
      而不是让容器盒子被元素高度撑开。
    */
    // 创建BScroll
    this.cateScroller = new BScroll('.cate-list-wrap',{
      probeType: 0,
      click: true
    })
    this.foodScroller = new BScroll('.food-list-wrap',{
      probeType: 3, //2: 不会监听惯性滑动（即只有当手指触摸期间才监听）; 3监听所有滑动
      click: true,
    })
    // 记录高度
    this.setTops()
    // 监听
    this.foodScroller.on('scroll', this.scrollHook)
    // this.foodScroller.on('scrollEnd', this.scrollHook)
    
  },
  data(){
    return {
      imgOrigin:'http://elm.cangdu.org/img/',
      cateIndex:0,
      foodData:[],
      // 购物车弹框可见标记
      showCarDialog:false,
      // 商品规格弹框可见标记
      showSpecsDialog:false,
      // 选择的商品规格下标
      activeSpecsKey:0,
      // 商品规格
      specifications:{},
      specProducts:[],

      // 点击'+'图标的坐标
      clientRect: {},
      // 小球落入购物车的动画
      showBall: false,
      // 购物车的动画
      showCartAnimation: false,
      // 分类滑动元素
      cateScroller: null,
      // 商品滑动元素
      foodScroller: null,
      // 距离顶部距离（负数）
      tops:[]

    }
  },
  computed:{
    ...mapState({
      shopcarts: state=>state.cart.shopcarts
    }),
    ...mapState('profile', ['latitude','longitude']),
    
    // 本店购物车
    shopcart(){
      return this.shopcarts[this.shopId]
    },
    // 购物车的商品列表
    cartFoodList(){
      if(!this.shopcart) return []
      const list = []
      Object.keys(this.shopcart).forEach(category_id=>{
        const category = this.shopcart[category_id]
        Object.keys(category).forEach(food_id=>{
          list.push({
            ...category[food_id],
            category_id,
            add_car_count:category[food_id].quantity
          })
        })
      })
      return list
    },
    // 购物车总费用
    cartTotalPrice(){
      return this.cartFoodList.reduce((sum, item)=>{
        return sum + (item.price * item.quantity)
      }, 0)
    },
    // 还差多少才送
    needOrderAmount(){
      if(this.shopDetail.float_minimum_order_amount){
        return this.shopDetail.float_minimum_order_amount - this.cartTotalPrice
      }else{
        return 1
      }
      
    },
    // 分类中加至购物车的数量, 是一个对象
    categoryAddNums(){
      const obj = {}
      this.cartFoodList.forEach(item=>{
        if(obj[item.category_id]){
          obj[item.category_id] += item.quantity
        }else{
          obj[item.category_id] = item.quantity
        }
      })
      return obj
    },
    // 购物车中总数目
    cartNum(){
      let sum = 0
      this.cartFoodList.forEach(item=>{
        sum += item.quantity
      })
      return sum
    }

  },
  methods:{
    ...mapActions('cart', [CLEAR_PRODUCTS]),
    
    // 点击分类
    onCateClick(index){
      console.log(index);
      this.cateIndex = index
      this.foodScroller.scrollTo(0, this.tops[index], 300)
    },

    setTops(){
      // 记录吸顶头的位置
      const arr = document.querySelectorAll('.cate-foods-wrap')
      let sum = 0
      this.tops.push(0)
      for(let item of arr){
        sum = sum-item.clientHeight //getBoundingClientRect().height
        console.log(sum, item.clientHeight);
        this.tops.push(sum)
      }
      
    },

    // 滑动的钩子
    scrollHook({x,y}){
      const headerHeight = this.$refs.foodListHeaderRef.clientHeight
      let index = 0
      // 如果y超过阈值，改变分类下标
      for(let i in this.tops){
        const bottomValue = this.tops[i]
        const topValue = this.tops[i]+headerHeight
        if(y<=topValue && y>bottomValue){ //下一个header遇到吸顶的header,让吸顶的header移动
          const offsetY = y - topValue
          console.log(y, headerHeight, offsetY);
          this.$refs.foodListHeaderRef.style.transform=`translateY(${offsetY}px)`
        }else{
          this.$refs.foodListHeaderRef.style.transform=`none`
        }
        if(y > bottomValue){
          index = i-1
          break
        }
      }
      if(index != this.cateIndex){
        this.cateIndex = index
      }
    },

    // 判断是否是新品
    judgeNew(attributes){
      for(let attr of attributes){
        if(attr && attr.icon_name === '新')
          return true
      }
      return false
    },
    // 判断是否是招牌
    judgeSign(attributes){
      for(let attr of attributes){
        if(attr && attr.icon_name === '招牌')
          return true
      }
      return false
    },
    // 点击购物车的蒙层
    handleCartOverlayClick(e){
      if(e.target.id === 'cartOverlay'){
        this.showCarDialog = false
      }
    },
    // 切换显示购物车弹框
    toggleCarDialog(){
      if(this.showCarDialog === true){
        this.showCarDialog = false
      }else{
        if(this.cartNum>0){
          this.showCarDialog = true
        }
      }
      
    },
    // 处理购物车内商品数量增删操作 
    handleCartCountChange({ category_id, item_id,type, add_car_count}){  
      // 实现购物车的elm-counter和商品列表的elm-counter联动
      // 从foodData中找到add_car_count数据并修改
      for(let category of this.foodData){
        if(category.id == category_id){
          for(let food of category.foods){
            if(food.item_id == item_id){
              //修改
              switch(type){
                case 'add':
                  food.add_car_count = add_car_count
                  break;
                case 'remove':
                  food.add_car_count--
                  break;
              }
            }
          }
        }
      }
    },
    // 打开规格选择框
    onSelectSpecs({specifications,specProducts},addToCart){
      this.activeSpecsKey = 0
      // console.log(specProducts);
      // console.log(addToCart);
      this.specifications = specifications
      this.specProducts = specProducts
      this.addToCart = addToCart
      this.showSpecsDialog = true
    },
    // 点击规格标签
    onSpecClick(index){
      this.activeSpecsKey = index
    },
    // 加入购物车
    addSpecToCart(){
      this.addToCart(this.specProducts[this.activeSpecsKey])
      this.showSpecsDialog = false
    },
    // 清空购物车
    handleCartClear(){
      console.log(this.shopId);
      if(this.cartNum<=0)
        return
      // 是否清空
      this.$dialog.confirm({
        width: '2.8rem',
        title: '清空购物车',
        cancelButtonText: '取消',
        confirmButtonText: '清空',
        confirmButtonColor: varStyles.primary
      })
      .then(() => { //确认清空
        // 清空store中数据
        this[CLEAR_PRODUCTS]({
          restaurant_id: this.shopId
        })
        // foodData的add_car_count置零
        for(let category of this.foodData){
          category.foods.forEach(food=>{
            food.add_car_count = 0
          })
        }
      }).catch(_=>null)
      
      
    },

    // 去结算，导航到确认订单页面
    navCheckout(){
      const {id,name, image_path} = this.shopDetail
      this.$router.push({
        name:'checkout',
        query:{restaurant_id:id, name, image_path}
      })
    },

    // 数据完成加入购物车后
    afterAddToCart(clientRect){
      this.showBall = true
      this.clientRect = clientRect
    },

    // 小球进购物车动画,小球下落的钩子函数
    beforeEnter(el){ //元素初始样式
      const {x, y} = this.clientRect
      el.style.transform=`translate(${22 + x - document.body.clientWidth }px, ${y-10}px)`
    },
    enter(el){  //元素最终样式
      // 原生js操作dom
      const {x, y} = this.clientRect
      let bottom = 60
      if(y<300){
        bottom = 90
      }else if(y>=300 && y<450){
        bottom = 60
      }else{
        bottom = 40
      }
      const distanceX = 50 - document.body.clientWidth
      const distanceY = document.body.clientHeight - y - bottom
      el.style.transform=`translate(${distanceX}px, ${y-10}px)`
      el.style.transition=`transform .6s linear`
      el.children[0].style.transform=`translateY(${distanceY}px)`
      el.children[0].style.transition=`transform .6s cubic-bezier(.4,-0.35,.88,.57)`
      //注意：el是translate后的位置是相对于最开始在html定义的位置（而非beforeEnter）
      // el的子元素的translate的位置是相对于父元素的
    },
    afterEnter(el){ //完成显示元素动画后
       // 重置过渡 或者..
      // el.style.transition=`none`
      // el.children[0].style.transition=`none`
      // 重新设置过渡，产生小停顿
      el.style.transition=`transform .2s linear`
      el.children[0].style.transition=`transform .2s linear`
      // 隐藏小球
      this.showBall = false
      // 小球完全落入购物车后
      console.log('add ok');
      this.showCartAnimation = true
      // 监听动画结束
    
      this.$refs.shopCartRef.addEventListener('transitionend', () => {
          this.showCartAnimation = false
      })
      this.$refs.shopCartRef.addEventListener('webkitAnimationEnd', () => {
          this.showCartAnimation = false
      })
    },

  },
  
}
</script>
<style lang='scss' scoped>
@import '../../../styles/mixin.scss';
@import '../../../styles/var.scss';
@keyframes cartAnimation {
  25%{
    transform: scale(.8);
  }
  50%{
    transform: scale(1.1);
  }
  75%{
    transform: scale(.9);
  }
}
.foods-container{
  display: flex;
  flex: 1;
  height: 100%;
  width: 100%;
  padding-bottom: .47rem;
  .badge{
    background: #f4432c;
    max-width: .5rem;
    min-width: .2rem;
    text-align: center;
    height: .2rem;
    line-height: .2rem;
    font-size: .12rem;
    font-weight: normal;
    color: #FFF;
    padding: 0 .06rem;
    border-radius: .1rem;
    @include text-ellipsis;
    transform: scale(.9);
  }
  // 侧边栏
  .cate-list-wrap{
    height: 100%; 
    width: 1rem;
    overflow-y: auto;
    background-color: #f5f5f5;
    .cate-list{
      .cate-item{
        height: .62rem;
        display: flex;
        align-items: center;
        padding: 0 .1rem;
        position: relative;
        .cate-text{
          @include two-line-ellipsis;
        }
        .cate-badge{
          position: absolute;
          top: .04rem;
          right: .02rem;
        }
      }
      .cate-item-active{
        font-size: .16rem;
        font-weight: 600;
        color: #666;
        background-color: #fff;
        border-left: 4px solid $primary;
      }
    }
  }
  // 商品分类头部
  .cate-food-header{
    width: 100%;
    flex: 1;
    display: flex;
    align-items: center;
    background-color: #f5f5f5;
    padding: .12rem .1rem;
    .food-header-title{
      color: #666;
      font-size: .17rem;
      font-weight: 700;
      display: inline-block;
      padding-top: .04rem;
    }
    .food-header-desc{
      font-size: .12rem;
      align-self: flex-end;
      margin-left: .12rem;
    }
    .food-header-more{
      position: absolute;
      right: .1rem;
    }
  }
  // 吸顶
  .sticky-fixed{
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
  }
  // 商品列表
  .food-list-wrap{
    flex: 1;
    width: 100%;
    height: 100%;
    overflow-y: auto;
    position: relative;
    .food-list{
      // 食物列表项
      .food-item-box{
        width: 100%;
        border-top: 1px solid #f5f5f5;
        display: flex;
        flex-direction: row;
        padding: .14rem .1rem 0 .09rem;
        position: relative;
        overflow: hidden;
        .attr-new{
          width: .44rem;
          height: .44rem;
          position: absolute;
          top: -.22rem;
          left: -.22rem;
          background: #4cd964;
          color: #FFF;
          font-size: .12rem;
          display: flex;
          flex-direction: column;
          justify-content: flex-end;
          align-items: center;
          transform: rotate(-45deg);
          p{
            margin-bottom: .01rem;
            transform: scale(.8);
          }
        }
        .foodicon{
          width: .47rem;
          height: .47rem;
          border-radius: .02rem;
          margin-right: .1rem;
        }
        
        // 食物文字信息
        .foodinfo{
          flex: 1;
          .row{
            flex: 1;
            position: relative;
            margin-bottom: .08rem;
            display: flex;
            justify-content: space-between;
            align-items: center;
            .food-title{
              font-size : .17rem;
              color: black;
              font-weight: 700;
              width: 1.8rem;
              @include text-ellipsis;
            }
            .food-labels{
              transform: scale(0.8);
              position: absolute;
              right: -.02rem;
              .food-label{
                font-size: .12rem;
                padding: .01rem .02rem;
                border: 1px solid #999;
                border-radius: .1rem;
                margin-left: .04rem;
              }
            }
            
            .food-desc{
              width: 1.8rem;
              font-size: .12rem;
              color: #999;
              @include two-line-ellipsis;
            }
            .food-tips{
              font-size: .13rem;
            }
            .food-fee>span{
              font-size: .12rem;
            }
            .food-fee>span:first-child{
              color: #f60;
            }
            .food-fee>span:nth-child(2){
              font-size: .17rem;
              font-weight: 700;
              color: #f60;
            }
          }
        }
      }
    }
  }
  
  // 购物车底栏
  .shop-car{
    width: 100%;
    position: fixed;
    z-index: 99;
    bottom: 0;
    left: 0;
    height: .47rem;
    background-color: #3d3d3f;
    display: flex;
    color: #FFF;
    .shop-car-icon{
      height: .50rem;
      width: .50rem;
      line-height: .47rem;
      background-color: #3d3d3f;
      border: .04rem solid #444;
      border-radius: 50%;
      margin-top: -.12rem;
      margin-left: .12rem;
      text-align: center;
      position: relative;
      .van-icon{
        color: #FFF;
        font-size: .30rem;
        margin-top: .04rem;
      }
      .cart-badge{
        position: absolute;
        top: -.1rem;
        right: -.04rem;
      }
    }
    .shop-car-icon-active{
      background-color: $primary;
    }
    .cart-animation{
      animation: .5s cartAnimation ease-in-out;
    }
    .shop-car-info{
      flex: 1;
      height: 100%;
      padding-left: .2rem;
      .info-main{
        height: .27rem;
        line-height: .27rem;
        font-size: .17rem;
        font-weight: 700;
      }
      .info-secd{
        font-size: .13rem;
      }
    }
    .shop-car-btn{
      height: 100%;
      line-height: .47rem;
      min-width: 1.17rem;
      font-size: .17rem;
      font-weight: 700;
      background-color: #535356;
      padding: 0 .1rem;
      text-align: center;
    }
  }
  // 购物车弹框
  .shop-car-food-wrap{
    width: 100%;
    background: #FFF;
    color: #666;
    font-size: .16rem;
    position: absolute;
    bottom: .47rem;
    left: 0;
    .shop-car-food-header{
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: .12rem .1rem;
      background-color: #eceff1;
      .car-clear-btn{
        *{
          vertical-align: middle;
        }
      }
    }
    .shop-car-food-list{
      min-height: .5rem;
      max-height: 3rem;
      padding: .02rem .1rem;
      .shop-car-food{
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: .12rem 0;
        line-height: .2rem;
        .shop-car-food-name-wrap{
          max-width: 50%;
          .shop-car-food-name{
            font-size: .16rem;
            font-weight:600;
            @include text-ellipsis;
          }
          .shop-car-food-spec{
            font-size: .12rem;
            @include text-ellipsis;
          }
        }
        
        .shop-car-food-right>*{
          vertical-align: middle;
        }
        .shop-car-food-price{
          font-size: .18rem;
          font-weight:600;
          color:#f60;
          margin-right: .2rem;
        }
        .shop-car-food-price::before{
          content: '￥';
          color: #f60;
          font-size: .17rem;
          font-weight: normal;
        }
      }
    }
  }
  // 规格弹框
  .van-popup{
    width: 70%;
    border-radius: .05rem;
    .close-icon{
      position: absolute;
      top: .04rem;
      right: .04rem;
      font-size: .26rem;
    }
    .specs-title{
      font-size: .17rem;
      font-weight: 600;
      height: .45rem;
      line-height: .45rem;
      text-align: center;
    }
    .specs-content{
      padding: .1rem .1rem;
      display: flex;
      flex-wrap: wrap;
      p{
        font-size: .16rem;
        width: 100%;
        padding: .08rem 0;
      }
      .specs-item{
        font-size: .13rem;
        padding: .08rem .1rem;
        border-radius: .04rem;
        border: 1px solid #ddd;
        margin-right: .1rem;
      }
      .specs-item-active{
        color: $primary;
        border-color: $primary;
      }
    }
    .specs-footer{
      margin-top: .2rem;
      background-color: #f5f5f5;
      height: .55rem;
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0 .1rem;
      .specs-price{
        color: #f60;
        font-size: .18rem;
        font-weight: 700;
      }
      .specs-price::before{
        content: '￥';
        color: #f60;
        font-size: .14rem;
        font-weight: 500;
      }
      .specs-add-btn{
        padding: .08rem;
        color:#fff;
        background-color: $primary;
        border-radius: .04rem;
      }
    }
  }
  // 小球
  .ball-box{
    position: fixed;
    top: 0;
    right: 0;
    // background: #f80;
    background-color: transparent;
    z-index: 9;
    .ball{
      width: .22rem;
      height: auto;
    }
  }
}
</style>